namespace C4F.DevKit.Bluetooth.SerialPortProfile
{
    #region Using Directives
    using System;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
    #endregion

    /// <summary>
    /// Exception class for Serial Port Profile.
    /// </summary>
    [Serializable]
    public class SPPException : Exception
    {
        #region Private Fields

        /// <summary>
        /// Specifies the type of error that has occurred.
        /// </summary>
        private SerialCommErrorType errorType;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets the type of error that caused the exception to be thrown.
        /// </summary>
        public SerialCommErrorType ErrorType
        {
            get
            { return this.errorType; }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes the ErrorType property with the specified errorType and
        /// sets the Message property of the new instance to a system-supplied 
        /// message.
        /// </summary>
        public SPPException(SerialCommErrorType errorType)
            : base()
        {
            this.errorType = errorType;
        }

        /// <summary>
        /// Initializes the exception with with the specified errorType and sets
        /// the Message property to the specified error message.
        /// </summary>
        /// <param name="errorType">Type of error that occured.</param>
        /// <param name="message">The message that describes the error.</param>
        public SPPException(SerialCommErrorType errorType, string message)
            : base(message)
        {
            this.errorType = errorType;
        }

        /// <summary>
        /// Initializes a new instance of the Exception class with the specified
        /// errorType, error message and a reference to the inner exception that
        /// is the cause of this exception.
        /// </summary>
        /// <param name="errorType">Type of error that occured.</param>
        /// <param name="message">The message that describes the error.</param>
        /// <param name="innerException">The exception that is the cause of this
        /// exception.</param>
        public SPPException(SerialCommErrorType errorType, string message,
                Exception innerException)
            : base(message, innerException)
        {
            this.errorType = errorType;
        }

        /// <summary>
        /// Initializes a new instance of this class with serialized data.
        /// </summary>
        /// <param name="info">The SerializationInfo that holds the serialized
        /// object data about the exception being thrown.</param>
        /// <param name="context">The StreamingContext that contains contextual
        /// information about the source or destination.</param>
        protected SPPException(SerializationInfo info,
            StreamingContext context)
            : base(info, context)
        {
            if (info != null)
                this.errorType = (SerialCommErrorType)info.GetValue(
                    "ErrorType", typeof(SerialCommErrorType));
        }

        #endregion

        #region Overriden Methods

        /// <summary>
        /// Sets the SerializationInfo with information about the exception. 
        /// </summary>
        /// <param name="info">The SerializationInfo that holds the serialized
        /// object data about the exception being thrown.</param>
        /// <param name="context">The StreamingContext that contains contextual
        /// information about the source or destination.</param>
        [SecurityPermission(SecurityAction.LinkDemand,
            Flags = SecurityPermissionFlag.SerializationFormatter)]
        public override void GetObjectData(SerializationInfo info,
            StreamingContext context)
        {
            base.GetObjectData(info, context);

            if (info != null)
                info.AddValue("ErrorType", this.errorType);
        }

        #endregion
    }
}